
#include "timer.h"
#include "bool.h"

#include <avr/io.h>
#include <avr/interrupt.h>
#include "PMARData.h"
#include "simpleEventHandler.h"

volatile static TimerType Timer[TIMERS_NUM];

//*****************************************************************
//              Timer Inititialize
//*****************************************************************
void timer_init (void){
	unsigned char i;
	for (i=0;i<TIMERS_NUM;i++){
		Timer[i].active=0;
		Timer[i].expired=0;
		Timer[i].Interval=0;
	}	
	
	TCCR1A=0;
	TCCR1B|= (1<<WGM12) | (1<<CS11) ; 
	OCR1A=10000;
	
	//TIMSK|= (1<<OCIE1A);
	ArrayTimerFunctions[0]=Timer0_Event;
	ArrayTimerFunctions[1]=Timer1_Event;
	ArrayTimerFunctions[2]=Timer2_Event;
	ArrayTimerFunctions[3]=Timer3_Event;
	ArrayTimerFunctions[4]=Timer4_Event;
	ArrayTimerFunctions[5]=Timer5_Event;
}

//*****************************************************************
//               Set a timer.
//*****************************************************************
void 	timer_set (unsigned char TimerNum, unsigned long IntervalValue){	
		Timer[TimerNum].Interval=IntervalValue;	
		Timer[TimerNum].active=true;
		Timer[TimerNum].expired=false;
		TIMSK|= (1<<OCIE1A);
}

//*****************************************************************
//               Reset a timer.
//*****************************************************************
void 	timer_reset (unsigned char TimerNum){
	Timer[TimerNum].Interval=0xFFFFFFFF;
	Timer[TimerNum].active=false;
	Timer[TimerNum].expired=false;	
}


//*****************************************************************
//               Restart the timer from the current point in time.
//*****************************************************************
unsigned char 	timer_expired (unsigned char TimerNum){
	if (Timer[TimerNum].active) {
		if (Timer[TimerNum].expired) {
			 Timer[TimerNum].active=false;
			 return true;
		}
	}
	else return false;
}

//*****************************************************************
//               Check if a timer has expired.
//*****************************************************************
unsigned long 	timer_remaining (unsigned char TimerNum){
	if (Timer[TimerNum].active) return Timer[TimerNum].Interval;
	else return 0;
}


//*****************************************************************
//               Timer0_Event 
//*****************************************************************
void Timer0_Event (void){
	SEQ_AddEvent(Timer0_Elapsed);
}

//*****************************************************************
//               Timer1_Event 
//*****************************************************************
void Timer1_Event (void){
	SEQ_AddEvent(Timer1_Elapsed);
}

//*****************************************************************
//               Timer2_Event 
//*****************************************************************
void Timer2_Event (void){
	SEQ_AddEvent(Timer2_Elapsed);
}

//*****************************************************************
//               Timer3_Event 
//*****************************************************************
void Timer3_Event (void){
	SEQ_AddEvent(Timer3_Elapsed);
}

//*****************************************************************
//               Timer4_Event 
//*****************************************************************
void Timer4_Event (void){
	SEQ_AddEvent(Timer4_Elapsed);
}

//*****************************************************************
//               Timer0_Event 
//*****************************************************************
void Timer5_Event (void){
	SEQ_AddEvent(Timer5_Elapsed);
}


//*****************************************************************
//              Interrupt Routine
//*****************************************************************
ISR(TIMER1_COMPA_vect) {
	unsigned char TimersDisabled=0;
   	unsigned char i;
   	for (i=0;i<TIMERS_NUM;i++){
	   	if (Timer[i].active) {  
			Timer[i].Interval--;
	   		if (Timer[i].Interval==0) {
				   ArrayTimerFunctions[i]();
			       Timer[i].expired=true;
			}
			//Timer[i].active=false;
	   		
		}
		else TimersDisabled++;
		//if  (TimersDisabled==TIMERS_NUM) TIMSK&= ~(1<<OCIE1A);
   	}
   
};
